﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DataTool;
using System.Activities;
using System.Activities.DurableInstancing;
using Common;

namespace OneGateWF
{
    public class ContestHost
    {
        static List<WorkflowApplication> list = new List<WorkflowApplication>();
        public void InvokeContestWF(CONTEST contest, List<string> Judge)
        {

            WorkflowApplication instance = CreateInstance(contest,Judge.ToArray());
            contest.Id = instance.Id;
            instance.Run();
            list.Add(instance);
        }

        public SqlWorkflowInstanceStore SetupInstanceStore()
        {
            SqlWorkflowInstanceStore store = new SqlWorkflowInstanceStore(@"Data Source=.\SQLEXPRESS;Initial Catalog=SqlWorkflowInstanceStore;Integrated Security=True;Asynchronous Processing=True");
            return store;
        }

        WorkflowApplication CreateInstance(CONTEST Contest,string[] Judge)
        {
            Activity wf = new ProcessContestActivity();
            Dictionary<string, object> inputs = new Dictionary<string, object>();
            inputs.Add("Contest", Contest);
            inputs.Add("Judge", Judge);
            WorkflowApplication instance = new WorkflowApplication(wf, inputs)
            {
                PersistableIdle = OnIdleAndPersistable,
                Completed = OnWorkflowCompleted,
                Idle = OnIdle
            };
            instance.InstanceStore = SetupInstanceStore();

            return instance;
        }

        void OnIdle(WorkflowApplicationIdleEventArgs e)
        {
        }

        PersistableIdleAction OnIdleAndPersistable(WorkflowApplicationIdleEventArgs e)
        {
            return PersistableIdleAction.Persist;
        }

        // executed when instance is persisted
        void OnWorkflowCompleted(WorkflowApplicationCompletedEventArgs e)
        {
        }

        WorkflowApplication CreateInstance()
        {
            Activity wf = new ProcessContestActivity();
            WorkflowApplication instance = new WorkflowApplication(wf)
            {
                PersistableIdle = OnIdleAndPersistable,
                Completed = OnWorkflowCompleted,
                Idle = OnIdle
            };
            instance.InstanceStore = SetupInstanceStore();

            return instance;
        }

        //public void Start(Guid Id)
        //{
        //    WorkflowApplication instance = CreateInstance();
        //    instance.Load(Id);
        //    instance.Run();
        //}

        WorkflowApplication getInstanceFrom(Guid Id)
        {
            WorkflowApplication instance;
            var ins = list.Where(x => x.Id == Id);
            if (ins.Count() == 0)
            {
                instance = CreateInstance();
                instance.Load(Id);
                list.Add(instance);
            }
            else
                instance = ins.FirstOrDefault();
            return instance;
        }

        public void SendSubmission(Guid Id,ContestSession cs )
        {
            WorkflowApplication instance = getInstanceFrom(Id);
            instance.ResumeBookmark("Wait4Contestant", cs);
            instance.Run();
        }

        public void StopAcceptPost(Guid Id)
        {
            WorkflowApplication instance = getInstanceFrom(Id);
            instance.ResumeBookmark("Wait4Contestant", new StopAcceptContestantSession());
            instance.Run();
        }

        public void GradePost(SubmissionGradeSession ss, Guid Id)
        {
            WorkflowApplication instance = getInstanceFrom(Id);
            instance.ResumeBookmark("SF_"+ss.Username+"_"+ss.SubId, ss);
            instance.Run();
        }

        public WorkflowApplication StaticCreateInstance()
        {
            return this.CreateInstance();
        }

        public static void LoadContest()
        {
            wfdbEntities db = new wfdbEntities();
            foreach (var i in db.CONTESTs.Where(x => x.Status == 1))
            {
                WorkflowApplication instance;
                instance = new ContestHost().StaticCreateInstance();
                instance.Load(i.Id);

                list.Add(instance);
                instance.Run();
            }
        }
    }
}
